#include <linux/seqlock.h>
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");

static int __init read_seqretry_init(void);
static void __exit read_seqretry_exit(void);

seqlock_t seqlock ;

int __init read_seqretry_init(void)
{
	int ret;
	seqlock_init( &seqlock );               //初始化顺序锁
	/*一下两行输出顺序锁中自旋锁字段值和顺序锁当前的顺序号*/
	printk("after seqlock_init, sequence: %d\n\n", seqlock.seqcount.sequence);
	write_seqlock( &seqlock );              //写者申请顺序锁
	printk("after write_seqlock, sequence: %d\n\n", seqlock.seqcount.sequence);
	write_sequnlock( &seqlock );            //写者释放顺序锁
	printk("after write_sequnlock, sequence: %d\n\n", seqlock.seqcount.sequence);
	

	// read_seqbegin 返回的是 顺序锁的序号
	//  如果下面循环的过程中，对 seqlock 还发生了任何修改，read_seqretry 就会返回 true，下面的循环就不止执行一次了
	do{
		ret = read_seqbegin( &seqlock );
		printk("ret = %d\n", ret );
	}while( read_seqretry(&seqlock, ret) );  //读操作代码块
	
	return 0;
}

void __exit read_seqretry_exit(void)
{
	printk("exit! \n");
}


module_init(read_seqretry_init);
module_exit(read_seqretry_exit);


/***
 *
 *	#define seqlock_init(x)                          \
	do {                                         \
		seqcount_init(&(x)->seqcount);           \
		spin_lock_init(&(x)->lock);              \
	} while (0)



	typedef struct seqcount {
		unsigned sequence;
	#ifdef CONFIG_DEBUG_LOCK_ALLOC
		struct lockdep_map dep_map;
	#endif
	} seqcount_t;


	顺序锁是对自旋锁的一种优化，对于顺序锁，读者不会被写者阻塞，也即是说，读者可以在写者对被顺序锁保护的共享资源进行写操作时继续读操作，而不必自旋在那里等待写者完成写操作，写者也不必等待所有读者完成读操作后再执行写操作。但是，写者与写者之间仍然是互斥的，即如果有写者在进行写操作，其他写者必须自旋在那里，直到该写者释放了顺序锁。

	
 *
 *
 *******/
